<script setup lang="ts">
import type { SelectValue } from 'ant-design-vue/es/select';

// ===== 导入依赖 =====
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue';
import { useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';
import { updatePreferences } from '@vben/preferences';
import { useUserStore } from '@vben/stores';

import { Col, Row, Select } from 'ant-design-vue';

// API导入
import {
  getAllOrgList,
  getBooKTypeRead,
  getIntegralTrend,
  getLeaderBoardTable,
  getReadTime,
  getReadTimeTable,
  getTop30,
  getUserNumber,
} from '#/api/largeVisualScreen/A';
import { requestClient } from '#/api/request.js';

// 组件导入
// @ts-ignore: JavaScript module without types
import useDraw from '../useDraw.js';
import columnarBalloon from './components/columnarBalloon.vue';
import columnarFolding from './components/columnarFolding.vue';
import horizontalColumnar from './components/horizontalColumnar.vue';
import horizontalScreeningColumnar from './components/horizontalScreeningColumnar.vue';
import pieChart from './components/pieChart.vue';
import radar from './components/radar.vue';
import ranking from './components/ranking.vue';

// ===== 类型定义 =====
interface OrgOption {
  value: string;
  label: string;
}

interface ChartData {
  xAxis?: string[];
  barData?: number[];
  lineData?: number[];
  units?: string[];
  activeData?: number[];
  memberData?: number[];
  totalActive?: number;
  totalMember?: number;
  books?: string[];
  values?: number[];
  organization?: string[];
}

interface RankingItem {
  rank: number;
  organization: string;
  name?: string;
  value: number;
}

interface SevenListData {
  xData: string[];
  seriesData: number[];
}

// ===== 常量定义 =====
const MONTHS = Array.from({ length: 12 }, (_, i) => `${i + 1}月`);

// ===== 基础配置和工具 =====
const userStore = useUserStore();
const router = useRouter();
const { appRef, calcRate, windowDraw, unWindowDraw } = useDraw();

// ===== 页面基础状态 =====
const loading = ref(true);
const title = ref('数据大屏A');
const enterpriseId = ref();

// 判断是否是管理员
const isAdmin = computed(() => {
  return userStore.$state.userRoles?.some(role => role === 'superadmin');
});

// ===== 用户和组织管理 =====
const userList = ref<{ userId: string; nickName: string; enterpriseId: number }[]>([]);
const orgList = ref<OrgOption[]>([]);

// 获取用户列表
const getUserList = async () => {
  const res = await requestClient.get('/system/user/list');
  userList.value = res.rows.filter((item: any) => item.userId !== 1);
};

// 获取组织列表
interface OrgListResponse {
  orgList: Array<{
    orgId: number;
    orgName: string;
  }>;
}

async function getOrgList() {
  const res = (await getAllOrgList()) as OrgListResponse;
  // 添加"全部"选项
  orgList.value = [
    { value: '0', label: '全部' },
    ...res.orgList.map((org) => ({
      value: org.orgId.toString(),
      label: org.orgName,
    })),
  ];
}

// ===== 定时器管理（拆开封装） =====
let chart1Timer: ReturnType<typeof setInterval>;
let chart2Timer: ReturnType<typeof setInterval>;
let chart3Timer: ReturnType<typeof setInterval>;
let chart4Timer: ReturnType<typeof setInterval>;
let chart5Timer: ReturnType<typeof setInterval>;
let chart6Timer: ReturnType<typeof setInterval>;
let chart7Timer: ReturnType<typeof setInterval>;

// ===== 图表1：阅读趋势图 =====
const chartTypes = [
  { id: 'readTime', name: '阅读时长趋势图', type: 1 },
  { id: 'readUsers', name: '阅读人数趋势图', type: 2 },
  { id: 'readBooks', name: '阅读本数趋势图', type: 3 },
  { id: 'readChapters', name: '阅读章节趋势图', type: 4 },
];

const oneObject = ref<ChartData>({});
const selectedOrg = ref('0');
const activeChart = ref('readTime');
const chartOneType = ref(1);

/**
 * 获取阅读趋势数据
 */
async function fetchChartOne() {
  const params: any = {
    type: chartOneType.value,
    orgId: selectedOrg.value,
  };

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getReadTime(params);
  oneObject.value = {
    xAxis: MONTHS,
    barData: res.barData,
    lineData: res.lineData,
  };
}

/**
 * 处理阅读趋势图组织切换
 */
function handleChartOneOrgChange(value: SelectValue) {
  if (typeof value === 'string' && value !== selectedOrg.value) {
    selectedOrg.value = value;
    if (chart1Timer) clearInterval(chart1Timer);
    fetchChartOne();
    chart1Timer = setInterval(fetchChartOne, 5000);
  }
}

/**
 * 处理阅读趋势图类型切换
 */
function handleChartOneTypeChange(chartId: string, chartType: number) {
  activeChart.value = chartId;
  chartOneType.value = chartType;
  if (chart1Timer) clearInterval(chart1Timer);
  fetchChartOne();
  chart1Timer = setInterval(fetchChartOne, 5000);
}

// ===== 图表2：用户统计 =====
const twoObject = ref<ChartData>({});

/**
 * 获取用户统计数据
 */
async function fetchChartTwo() {
  const params: any = {};

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getUserNumber(params);
  twoObject.value = {
    units: res.units,
    activeData: res.activeData,
    memberData: res.memberData,
    totalActive: res.totalActive,
    totalMember: res.totalMember,
  };
}

// ===== 图表3：热门书籍 =====
const threeObject = ref<ChartData>({ books: [] });
const selectedThreeOrg = ref('0');

/**
 * 获取热门书籍数据
 */
async function fetchChartThree() {
  const params: any = { orgId: selectedThreeOrg.value };
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }
  const res = await getTop30(params);
  threeObject.value = {
    books: res.books.slice(0, 20),
    values: res.values.slice(0, 20),
    // organization: res.organization.slice(0, 25),
  };
}

/**
 * 处理热门书籍组织切换
 */
function handleChartThreeOrgChange(value: SelectValue) {
  if (typeof value === 'string' && value !== selectedThreeOrg.value) {
    selectedThreeOrg.value = value;
    if (chart3Timer) clearInterval(chart3Timer);
    fetchChartThree();
    chart3Timer = setInterval(fetchChartThree, 5000);
  }
}

// ===== 图表4：书籍类型 =====
const fourObject = ref({});
const selectedFourOrg = ref('0');

/**
 * 获取书籍类型数据
 */
async function fetchChartFour() {
  const params: any = { orgId: selectedFourOrg.value };

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getBooKTypeRead(params);
  fourObject.value = {
    chartData: res.chartData,
    indicators: res.indicators,
  };
}

/**
 * 处理书籍类型组织切换
 */
function handleChartFourOrgChange(value: SelectValue) {
  if (typeof value === 'string' && value !== selectedFourOrg.value) {
    selectedFourOrg.value = value;
    if (chart4Timer) clearInterval(chart4Timer);
    fetchChartFour();
    chart4Timer = setInterval(fetchChartFour, 5000);
  }
}

// ===== 图表5：阅读时长排行 =====
const chartTypesFive = [
  { id: 'Individual', name: '个人阅读时长' },
  { id: 'Organization', name: '组织阅读时长' },
];

const rankingData = ref<RankingItem[]>([]);
const activeFiveChart = ref('Individual');

/**
 * 获取阅读时长排行数据
 */
async function fetchChartFive() {
  const tableType = activeFiveChart.value === 'Individual' ? 1 : 2;
  const params: any = { tableType };

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getReadTimeTable(params);
  rankingData.value = res.rankingData;
}

/**
 * 处理阅读时长排行类型切换
 */
function handleChartFiveTypeChange(chartId: string) {
  activeFiveChart.value = chartId;
  if (chart5Timer) clearInterval(chart5Timer);
  fetchChartFive();
  chart5Timer = setInterval(fetchChartFive, 5000);
}

// ===== 图表6：积分排行 =====
const chartTypesSix = [
  { id: 'Individual', name: '个人积分排行' },
  { id: 'Organization', name: '组织积分排行' },
];

const pieChartData = ref<
  Array<{ name: string; organization?: string; value: number }>
>([]);
const activeSixChart = ref('Individual');

/**
 * 获取积分排行数据
 */
async function fetchChartSix() {
  const tableType = activeSixChart.value === 'Individual' ? 1 : 2;
  const params: any = { tableType };

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getLeaderBoardTable(params);
  pieChartData.value = res.rankingData;
}

/**
 * 处理积分排行类型切换
 */
function handleChartSixTypeChange(chartId: string) {
  activeSixChart.value = chartId;
  if (chart6Timer) clearInterval(chart6Timer);
  fetchChartSix();
  chart6Timer = setInterval(fetchChartSix, 5000);
}

// ===== 图表7：积分趋势 =====
const seventList = ref<SevenListData>({ xData: [], seriesData: [] });
const selectedSevenOrg = ref('0');

/**
 * 获取积分趋势数据
 */
async function fetchChartSeven() {
  const params: any = { orgId: selectedSevenOrg.value };

  // 如果是管理员且选择了企业，添加企业ID参数
  if (isAdmin.value && enterpriseId.value) {
    params.enterpriseId = enterpriseId.value;
  }

  const res = await getIntegralTrend(params);
  seventList.value = {
    xData: MONTHS,
    seriesData: res.seriesData,
  };
}

/**
 * 处理积分趋势组织切换
 */
function handleChartSevenOrgChange(value: SelectValue) {
  if (typeof value === 'string' && value !== selectedSevenOrg.value) {
    selectedSevenOrg.value = value;
    if (chart7Timer) clearInterval(chart7Timer);
    fetchChartSeven();
    chart7Timer = setInterval(fetchChartSeven, 5000);
  }
}

/**
 * 处理企业切换
 */
function handleEnterpriseChange() {
  // 清除所有定时器
  if (chart1Timer) clearInterval(chart1Timer);
  if (chart2Timer) clearInterval(chart2Timer);
  if (chart3Timer) clearInterval(chart3Timer);
  if (chart4Timer) clearInterval(chart4Timer);
  if (chart5Timer) clearInterval(chart5Timer);
  if (chart6Timer) clearInterval(chart6Timer);
  if (chart7Timer) clearInterval(chart7Timer);

  // 重新获取所有图表数据并启动定时器
  fetchChartOne();
  chart1Timer = setInterval(fetchChartOne, 5000);

  fetchChartTwo();
  chart2Timer = setInterval(fetchChartTwo, 5000);

  fetchChartThree();
  chart3Timer = setInterval(fetchChartThree, 5000);

  fetchChartFour();
  chart4Timer = setInterval(fetchChartFour, 5000);

  fetchChartFive();
  chart5Timer = setInterval(fetchChartFive, 5000);

  fetchChartSix();
  chart6Timer = setInterval(fetchChartSix, 5000);

  fetchChartSeven();
  chart7Timer = setInterval(fetchChartSeven, 5000);
}

// ===== 工具方法 =====
/**
 * 关闭加载动画
 */
function closeLoading() {
  setTimeout(() => (loading.value = false), 2000);
}

/**
 * 处理ESC键退出
 */
function handleEscKeydown(event: KeyboardEvent) {
  if (event.key === 'Escape') {
    router.back();
    updateScreenPreferences('default');
  }
}

/**
 * 更新屏幕偏好设置
 */
function updateScreenPreferences(mode: 'default' | 'full') {
  return updatePreferences({
    app: { layout: mode === 'full' ? 'full-content' : 'sidebar-nav' },
    header: { enable: mode !== 'full' },
    sidebar: { collapsed: mode === 'full' },
    tabbar: { enable: false },
  });
}

// ===== 生命周期处理 =====
/**
 * 初始化数据和事件监听
 */
async function init() {
  try {
    closeLoading();
    calcRate();
    windowDraw();
    await getOrgList();
    window.addEventListener('keydown', handleEscKeydown);
    await updateScreenPreferences('full');

    // 启动所有图表定时器
    fetchChartOne();
    chart1Timer = setInterval(fetchChartOne, 5000);

    fetchChartTwo();
    chart2Timer = setInterval(fetchChartTwo, 5000);

    fetchChartThree();
    chart3Timer = setInterval(fetchChartThree, 5000);

    // fetchChartFour();
    // chart4Timer = setInterval(fetchChartFour, 5000);

    // fetchChartFive();
    // chart5Timer = setInterval(fetchChartFive, 5000);

    // fetchChartSix();
    // chart6Timer = setInterval(fetchChartSix, 5000);

    // fetchChartSeven();
    // chart7Timer = setInterval(fetchChartSeven, 5000);
  } catch (error) {
    console.error('初始化失败:', error);
    loading.value = false;
  }
}

/**
 * 清理事件监听和定时器
 */
function cleanup() {
  try {
    unWindowDraw();
    window.removeEventListener('keydown', handleEscKeydown);

    // 清理所有定时器
    if (chart1Timer) clearInterval(chart1Timer);
    if (chart2Timer) clearInterval(chart2Timer);
    if (chart3Timer) clearInterval(chart3Timer);
    if (chart4Timer) clearInterval(chart4Timer);
    if (chart5Timer) clearInterval(chart5Timer);
    if (chart6Timer) clearInterval(chart6Timer);
    if (chart7Timer) clearInterval(chart7Timer);
  } catch (error) {
    console.error('清理失败:', error);
  }
}

// 生命周期钩子
onMounted(async () => {
  // 管理员初始化
  if (isAdmin.value) {
    await getUserList();
    enterpriseId.value = userList?.value[0]?.enterpriseId;
  }

  nextTick(() => {
    if (appRef.value) {
      init();
    }
  });
});

onUnmounted(() => {
  cleanup();
});
</script>

<template>
  <Page :auto-content-height="true" class="map-container">
    <div id="map-box" ref="appRef">
      <div class="bg">
        <dv-loading v-if="loading">Loading...</dv-loading>
        <div v-else style="width: 100%; height: 100%">
          <!-- 页面标题 -->
          <div class="header">
            <div class="move-line"></div>
            <div class="header-title">{{ title }}</div>
            <img class="header-bg" src="../../../assets/header-04.png" />
            <Select v-if="isAdmin" v-model:value="enterpriseId" placeholder="请选择企业" class="org-select1"
              @change="handleEnterpriseChange">
              <Select.Option v-for="org in userList" :key="org.userId" :value="org.enterpriseId">
                {{ org.nickName }}
              </Select.Option>
            </Select>
          </div>

          <!-- 图表布局 -->
          <Row :gutter="[10, 10]" style="height: calc(100% - 60px); padding: 10px 0">
            <!-- 上半部分 -->
            <Col :span="24" class="h-2/3">
            <Row :gutter="10" style="height: 100%">
              <!-- 图表1：阅读趋势图 -->
              <Col :span="16">
              <dv-border-box-13 class="p-2.5">
                <div class="chart-header">
                  <div class="chart-types">
                    <div v-for="chart in chartTypes" :key="chart.id" class="chart-type-item"
                      :class="{ active: activeChart === chart.id }" @click="
                        handleChartOneTypeChange(chart.id, chart.type)
                        ">
                      {{ chart.name }}
                    </div>
                  </div>
                  <Select :value="selectedOrg" placeholder="请选择组织" class="org-select" @change="handleChartOneOrgChange">
                    <Select.Option v-for="org in orgList" :key="org.value" :value="org.value">
                      {{ org.label }}
                    </Select.Option>
                  </Select>
                </div>
                <columnarFolding :height="400" :chart-data="oneObject" />
              </dv-border-box-13>
              </Col>

              <!-- 右侧图表 -->
              <Col :span="8">
              <!-- 图表2：用户统计 -->
              <div style="height: calc(50% - 8px); margin-bottom: 10px">
                <dv-border-box-8>
                  <horizontalColumnar :chart-data="twoObject" />
                </dv-border-box-8>
              </div>

              <!-- 图表3：热门书籍 -->
              <div style="height: calc(50% - 8px); margin-top: 10px">
                <dv-border-box-8>
                  <div class="chart-header">
                    <div>受欢迎书籍TOP30</div>
                    <Select :value="selectedThreeOrg" placeholder="请选择组织" class="org-select"
                      @change="handleChartThreeOrgChange">
                      <Select.Option v-for="org in orgList" :key="org.value" :value="org.value">
                        {{ org.label }}
                      </Select.Option>
                    </Select>
                  </div>
                  <horizontalScreeningColumnar :chart-data="threeObject" />
                </dv-border-box-8>
              </div>
              </Col>
            </Row>
            </Col>

            <!-- 下半部分 -->
            <Col :span="24" class="h-1/3">
            <Row :gutter="10" style="width: 100%; height: 100%">
              <!-- 图表4：书籍类型 -->
              <Col :span="6">
              <dv-border-box-8>
                <div class="chart-header">
                  <div>各类书籍阅读情况</div>
                  <Select :value="selectedFourOrg" placeholder="请选择组织" class="org-select"
                    @change="handleChartFourOrgChange">
                    <Select.Option v-for="org in orgList" :key="org.value" :value="org.value">
                      {{ org.label }}
                    </Select.Option>
                  </Select>
                </div>
                <radar :chart-data="fourObject" />
              </dv-border-box-8>
              </Col>

              <!-- 图表5：阅读时长排行 -->
              <Col :span="6">
              <dv-border-box-8>
                <div class="p-2">
                  <div class="chart-types">
                    <div v-for="chart in chartTypesFive" :key="chart.id" class="chart-type-item"
                      :class="{ active: activeFiveChart === chart.id }" @click="handleChartFiveTypeChange(chart.id)">
                      {{ chart.name }}
                    </div>
                  </div>
                  <ranking :type="activeFiveChart === 'Individual'
                    ? 'personal'
                    : 'organization'
                    " :title="activeFiveChart === 'Individual'
                      ? '个人阅读时长排行'
                      : '组织阅读时长排行'
                      " :data="rankingData" />
                </div>
              </dv-border-box-8>
              </Col>

              <!-- 图表6：积分排行 -->
              <Col :span="6">
              <dv-border-box-8>
                <div class="p-2">
                  <div class="chart-types">
                    <div v-for="chart in chartTypesSix" :key="chart.id" class="chart-type-item"
                      :class="{ active: activeSixChart === chart.id }" @click="handleChartSixTypeChange(chart.id)">
                      {{ chart.name }}
                    </div>
                  </div>
                  <pieChart :type="activeSixChart === 'Individual'
                    ? 'personal'
                    : 'organization'
                    " :chart-data="pieChartData" />
                </div>
              </dv-border-box-8>
              </Col>

              <!-- 图表7：积分趋势 -->
              <Col :span="6">
              <dv-border-box-8>
                <div class="chart-header">
                  <div>组织积分趋势</div>
                  <Select :value="selectedSevenOrg" placeholder="请选择组织" class="org-select"
                    @change="handleChartSevenOrgChange">
                    <Select.Option v-for="org in orgList" :key="org.value" :value="org.value">
                      {{ org.label }}
                    </Select.Option>
                  </Select>
                </div>
                <columnarBalloon :chart-data="seventList" />
              </dv-border-box-8>
              </Col>
            </Row>
            </Col>
          </Row>
        </div>
      </div>
    </div>
  </Page>
</template>

<style lang="scss" scoped>
// ===== 容器样式 =====
.map-container {
  width: 100%;
  height: 100%;
  padding: 0 !important;
  margin: 0 !important;
  background-color: black;

  :deep(.h-full) {
    padding: 0 !important;
  }

  #map-box {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1920px;
    height: 1080px;
    color: #d3d6dd;
    background-color: #ffebcd;
    transform: translate(-50%, -50%);
    transform-origin: left top;

    .bg {
      box-sizing: border-box;
      width: 100%;
      height: 100%;
      padding: 12px 12px 0;
      background-image: url('../../../assets/pageBg.png');
      background-position: center center;
      background-size: cover;
    }
  }
}

// ===== 头部样式 =====
.header {
  position: relative;
  width: 100%;
  height: 50px;

  @keyframes move-left-to-right {
    from {
      transform: translateX(0);
    }

    to {
      transform: translateX(calc(100vw - 106px));
    }
  }

  .move-line {
    position: absolute;
    bottom: -11px;
    left: 0;
    width: 106px;
    height: 28px;
    background: url('../../../assets/line-bg.png') no-repeat;
    background-size: 100% 100%;
    animation: move-left-to-right 4s linear infinite;
  }

  .header-title {
    min-width: 250px;
    margin: 0 50px;
    font-size: 20px;
    font-weight: 900;
    line-height: 2.8rem;
    color: transparent;
    text-align: center;
    letter-spacing: 4px;
    background-image: linear-gradient(92deg,
        #0072ff 0%,
        #00eaff 48.8525%,
        #01aaff 100%);
    background-clip: text;
  }

  .header-bg {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    z-index: 0;
    width: 100%;
    height: 3.84rem;
    margin: 0 auto;
  }
}

// ===== 图表样式 =====
.chart-header {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  border-radius: 4px;
}

.chart-types {
  display: flex;
  gap: 20px;
}

.chart-type-item {
  position: relative;
  padding: 8px 16px;
  overflow: hidden;
  font-size: 14px;
  color: rgb(0 242 254 / 70%);
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: 4px;
  transition: all 0.3s ease;

  &::before {
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 2px;
    content: '';
    background: linear-gradient(90deg, transparent, rgb(0 242 254 / 80%));
    transition: 0.5s;
  }

  &:hover {
    color: rgb(0 242 254 / 100%);
    border-color: rgb(0 242 254 / 30%);
    box-shadow: 0 0 10px rgb(0 242 254 / 10%);

    &::before {
      left: 100%;
    }
  }

  &.active {
    color: #fff;
    background: linear-gradient(90deg,
        rgb(0 242 254 / 30%) 0%,
        rgb(0 242 254 / 10%) 100%);
    border-color: rgb(0 242 254 / 50%);
    box-shadow: 0 0 15px rgb(0 242 254 / 20%);
  }
}

// ===== 选择器样式 =====
.org-select {
  width: 160px;

  :deep(.ant-select-selector) {
    color: #fff !important;
    background: rgb(1 36 86 / 50%) !important;
    border-color: rgb(0 242 254 / 30%) !important;
  }

  :deep(.ant-select-arrow) {
    color: rgb(0 242 254 / 70%);
  }

  &:hover {
    :deep(.ant-select-selector) {
      border-color: rgb(0 242 254 / 80%) !important;
      box-shadow: 0 0 10px rgb(0 242 254 / 20%) !important;
    }
  }
}

.org-select1 {
  width: 160px;
  position: absolute;
  left: 0;
  top: 0;

  :deep(.ant-select-selector) {
    color: #fff !important;
    background: rgb(1 36 86 / 50%) !important;
    border-color: rgb(0 242 254 / 30%) !important;
  }

  :deep(.ant-select-arrow) {
    color: rgb(0 242 254 / 70%);
  }

  &:hover {
    :deep(.ant-select-selector) {
      border-color: rgb(0 242 254 / 80%) !important;
      box-shadow: 0 0 10px rgb(0 242 254 / 20%) !important;
    }
  }
}
</style>